package crypto

import (
	"crypto/aes"
	"crypto/cipher"
	"crypto/hmac"
	"crypto/md5"
	"crypto/sha1"
	"crypto/sha256"
	"crypto/sha512"
	"encoding/hex"
	"hash"
)

//MD5 计算字符串的md5 并转换为字符串
func MD5(str string) string {
	sumBytes := md5.Sum([]byte(str))
	return hex.EncodeToString(sumBytes[:])
}

//sha1 算法
func Sha1(data string) string {
	h := sha1.New()
	h.Write([]byte(data))
	return hex.EncodeToString(h.Sum(nil))
}

//sha256 算法
func Sha256(data string) string {
	h := sha256.New()
	h.Write([]byte(data))
	return hex.EncodeToString(h.Sum(nil))
}

//hmac 算法， algo 支持 sha1、sha256、sha512、md5 哈希算法
func Hmac(key, data, algo string) string {
	var f func() hash.Hash
	if algo == "sha1" {
		f = sha1.New
	} else if algo == "sha256" {
		f = sha256.New
	} else if algo == "sha512" {
		f = sha512.New
	} else {
		f = md5.New
	}

	h := hmac.New(f, []byte(key))
	h.Write([]byte(data))
	return hex.EncodeToString(h.Sum(nil))
}

//AesEncrypt AES加密，key的长度必须是16,24,32位
func AesEncrypt(key string, msg []byte) (ret []byte, err error) {
	bs := []byte(key)
	block, err := aes.NewCipher(bs)
	if err != nil {
		return nil, err
	}

	ret = make([]byte, len(msg))
	var iv = bs[:aes.BlockSize]
	encrypter := cipher.NewCFBEncrypter(block, iv)
	encrypter.XORKeyStream(ret, msg)

	return
}

//AesDecrypt AES 解密，key的长度必须是16,24,32位
func AesDecrypt(key string, src []byte) (ret []byte, err error) {
	defer func() {
		//错误处理
		if e := recover(); e != nil {
			err, _ = e.(error)
		}
	}()

	bs := []byte(key)

	block, err := aes.NewCipher(bs)
	if err != nil {
		return nil, err
	}

	ret = make([]byte, len(src))
	var iv = bs[:aes.BlockSize]
	decrypter := cipher.NewCFBDecrypter(block, iv)
	decrypter.XORKeyStream(ret, src)

	return
}
